package com.google.code.csf.locators;

import com.google.code.csf.ServiceLocator;

import javax.xml.namespace.QName;

public abstract class AbstractWebServiceServiceLocator implements ServiceLocator {
    private final Object preparationMonitor = new Object();
    private String endpointAddress;
    private String password;
    private boolean maintainSession;
    private String username;
    private QName name;
    private Class portInterface;
    private Object jaxService;

    protected abstract Object createJaxService() throws Throwable;

    public void release(Object toRelease) {

    }

    public final QName getQName() {
        return name;
    }

    public final void setQName(QName name) {
        this.name = name;
    }

    public final String getEndpointAddress() {
        return endpointAddress;
    }

    public final void setEndpointAddress(String endpointAddress) {
        this.endpointAddress = endpointAddress;
    }

    public final String getPassword() {
        return password;
    }

    public final void setPassword(String password) {
        this.password = password;
    }

    public final boolean isMaintainSession() {
        return maintainSession;
    }

    public final void setMaintainSession(boolean maintainSession) {
        this.maintainSession = maintainSession;
    }

    public final String getUsername() {
        return username;
    }

    public final void setUsername(String username) {
        this.username = username;
    }

    public final Class getPortInterface() {
        return portInterface;
    }

    public final void setPortInterface(Class portInterface) {
        this.portInterface = portInterface;
    }

    public final Object getJaxService() {
        return jaxService;
    }

    public final void setJaxService(Object jaxService) {
        this.jaxService = jaxService;
    }

    protected Object locateJaxService() throws Throwable {
        synchronized (preparationMonitor) {
            Object service = getJaxService();
            if (service == null) {
                service = createJaxService();
            }

            return getQName() == null
                    ? service.getClass().getMethod("getPort", new Class[]{Class.class}).invoke(service, new Object[]{getPortInterface()})
                    : service.getClass().getMethod("getPort", new Class[]{QName.class, Class.class}).invoke(service, new Object[]{getQName(), getPortInterface()});
        }
    }
}
